home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 4364 / 4364.xpi / chrome / elemhidehelper.jar / content / aardvark.js next >
Text File  |  2009-07-01  |  19KB  |  688 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Aardvark Firefox extension.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Rob Brown.
  18.  * Portions created by the Initial Developer are Copyright (C) 2006-2007
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  * Wladimir Palant
  23.  *
  24.  * ***** END LICENSE BLOCK ***** */
  25.  
  26. /**********************************
  27.  * General element selection code *
  28.  **********************************/
  29.  
  30. var ehhAardvark = {
  31.     browser: null,
  32.     selectedElem: null,
  33.     commentElem : null,
  34.     mouseX: -1,
  35.     mouseY: -1,
  36.     commandLabelTimeout: 0,
  37.     borderElems: null,
  38.     labelElem: null
  39. };
  40.  
  41. ehhAardvark.start = function(browser) {
  42.     if (!ehhCanSelect(browser))
  43.         return;
  44.  
  45.     if (!("viewSourceURL" in this)) {
  46.         // Firefox/Thunderbird and SeaMonkey have different viewPartialSource URLs
  47.         var urls = [
  48.             "chrome://global/content/viewPartialSource.xul",
  49.             "chrome://navigator/content/viewPartialSource.xul"
  50.         ];
  51.         this.viewSourceURL = null;
  52.         for (var i = 0; i < urls.length && !this.viewSourceURL; i++) {
  53.             var request = new XMLHttpRequest();
  54.             request.open("GET", urls[i], false);
  55.             try {
  56.                 request.send(null);
  57.                 this.viewSourceURL = urls[i];
  58.             } catch (e) {}
  59.         }
  60.  
  61.         if (!this.viewSourceURL) {
  62.             for (i = 0; i < this.commands.length; i++)
  63.                 if (this.commands[i] == "viewSourceWindow")
  64.                     this.commands.splice(i--, 1);
  65.         }
  66.     }
  67.  
  68.     browser.addEventListener("click", this.mouseClick, true);
  69.     browser.addEventListener("mouseover", this.mouseOver, true);
  70.     browser.addEventListener("keypress", this.keyPress, true);
  71.     browser.addEventListener("mousemove", this.mouseMove, true);
  72.     browser.contentWindow.addEventListener("pagehide", this.pageHide, true);
  73.  
  74.     browser.contentWindow.focus();
  75.  
  76.     this.browser = browser;
  77.  
  78.     if (!this.labelElem)
  79.         this.makeElems();
  80.  
  81.     this.initHelpBox();
  82.  
  83.     var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  84.                                                             .getService(Components.interfaces.nsIPrefService);
  85.     var branch = prefService.getBranch("extensions.adblockplus.");
  86.     var showMenu = true;
  87.     try {
  88.         showMenu = branch.getBoolPref("ehh.showhelp");
  89.     } catch(e) {}
  90.  
  91.     if (showMenu)
  92.         this.showMenu();
  93. }
  94.  
  95. ehhAardvark.doCommand = function(command, event) {
  96.     if (this[command](this.selectedElem)) {
  97.         this.showCommandLabel(this.commands[command + "_key"], this.commands[command + "_label"]);
  98.         if (event)
  99.             event.stopPropagation();
  100.     }
  101.     if (event)
  102.         event.preventDefault();
  103. }
  104.  
  105. ehhAardvark.showCommandLabel = function(key, label) {
  106.     if (this.commandLabelTimeout)
  107.         clearTimeout(this.commandLabelTimeout);
  108.  
  109.     document.getElementById("ehh-commandlabel-key").setAttribute("value", key);
  110.     document.getElementById("ehh-commandlabel-label").setAttribute("value", label);
  111.  
  112.     var commandLabel = document.getElementById("ehh-commandlabel");
  113.     commandLabel.showPopup(document.documentElement, this.mouseX, this.mouseY, "tooltip", "topleft", "topleft");
  114.  
  115.     this.commandLabelTimeout = setTimeout(function() {
  116.         commandLabel.hidePopup();
  117.         ehhAardvark.commandLabelTimeout = 0;
  118.     }, 400);
  119. }
  120.  
  121. ehhAardvark.initHelpBox = function() {
  122.     var helpBoxRows = document.getElementById("ehh-helpbox-rows");
  123.     if (helpBoxRows.firstChild)
  124.         return;
  125.  
  126.     // Help box hasn't been filled yet, need to do it now
  127.     var stringService = Components.classes["@mozilla.org/intl/stringbundle;1"]
  128.                                                                 .getService(Components.interfaces.nsIStringBundleService);
  129.     var strings = stringService.createBundle("chrome://elemhidehelper/locale/global.properties");
  130.  
  131.     for (var i = 0; i < this.commands.length; i++) {
  132.         var command = this.commands[i];
  133.         var key = strings.GetStringFromName("command." + command + ".key");
  134.         var label = strings.GetStringFromName("command." + command + ".label");
  135.         this.commands[command + "_key"] = key.toLowerCase();
  136.         this.commands[command + "_label"] = label;
  137.  
  138.         var row = document.createElement("row");
  139.         helpBoxRows.appendChild(row);
  140.  
  141.         var element = document.createElement("description");
  142.         element.setAttribute("value", key);
  143.         element.className = "key";
  144.         row.appendChild(element);
  145.  
  146.         element = document.createElement("description");
  147.         element.setAttribute("value", label);
  148.         element.className = "label";
  149.         row.appendChild(element);
  150.     }
  151. }
  152.  
  153. ehhAardvark.onMouseClick = function(event) {
  154.     if (event.button != 0 || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)
  155.         return;
  156.  
  157.     this.doCommand("select", event);
  158. }
  159.  
  160. ehhAardvark.onMouseOver = function(event) {
  161.     var elem = event.originalTarget;
  162.     var aardvarkLabel = elem;
  163.     while (aardvarkLabel && !("ehhAardvarkLabel" in aardvarkLabel))
  164.         aardvarkLabel = aardvarkLabel.parentNode;
  165.  
  166.     if (elem == null || aardvarkLabel)
  167.     {
  168.         this.clearBox ();
  169.         return;
  170.     }
  171.  
  172.     if (elem == this.selectedElem)
  173.         return;
  174.     
  175.     this.showBoxAndLabel (elem, this.makeElementLabelString (elem));
  176. }
  177.  
  178. ehhAardvark.onKeyPress = function(event) {
  179.     if (event.altKey || event.ctrlKey || event.metaKey)
  180.         return;
  181.  
  182.     var command = null;
  183.     if (event.keyCode == event.DOM_VK_ESCAPE)
  184.         command = "quit";
  185.     else if (event.keyCode == event.DOM_VK_RETURN)
  186.         command = "select";
  187.     else if (event.charCode) {
  188.         var key = String.fromCharCode(event.charCode).toLowerCase();
  189.         var commands = this.commands;
  190.         for (var i = 0; i < commands.length; i++)
  191.             if (commands[commands[i] + "_key"] == key)
  192.                 command = commands[i];
  193.     }
  194.  
  195.     if (command)
  196.         this.doCommand(command, event);
  197. }
  198.  
  199. ehhAardvark.onPageHide = function(event) {
  200.     this.doCommand("quit", null);
  201. }
  202.  
  203. ehhAardvark.onMouseMove = function(event) {
  204.     this.mouseX = event.screenX;
  205.     this.mouseY = event.screenY;
  206. }
  207.  
  208. // Makes sure event handlers like ehhAardvark.keyPress redirect
  209. // to the real handlers (ehhAardvark.onKeyPress in this case) with
  210. // correct this pointer.
  211. ehhAardvark.generateEventHandlers = function(handlers) {
  212.     var generator = function(handler) {
  213.         return function(event) {ehhAardvark[handler](event)};
  214.     };
  215.  
  216.     for (var i = 0; i < handlers.length; i++) {
  217.         var handler = "on" + handlers[i][0].toUpperCase() + handlers[i].substr(1);
  218.         this[handlers[i]] = generator(handler);
  219.     }
  220. }
  221. ehhAardvark.generateEventHandlers(["mouseClick", "mouseOver", "keyPress", "pageHide", "mouseMove"]);
  222.  
  223. ehhAardvark.appendDescription = function(node, value, className) {
  224.     var descr = document.createElement("description");
  225.     descr.setAttribute("value", value);
  226.     if (className)
  227.         descr.setAttribute("class", className);
  228.     node.appendChild(descr);
  229. }
  230.  
  231. /***************************
  232.  * Highlight frame display *
  233.  ***************************/
  234.  
  235. //-------------------------------------------------
  236. // create the box and tag etc (done once and saved)
  237. ehhAardvark.makeElems = function ()
  238. {
  239.     this.borderElems = [];
  240.     var d, i;
  241.  
  242.     for (i=0; i<4; i++)
  243.     {
  244.         d = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
  245.         d.style.display = "none";
  246.         d.style.position = "absolute";
  247.         d.style.height = "0px";
  248.         d.style.width = "0px";
  249.         d.style.zIndex = "65534";
  250.         if (i < 2)
  251.             d.style.borderTop = "2px solid #f00";
  252.         else
  253.             d.style.borderLeft = "2px solid #f00";
  254.         d.ehhAardvarkLabel = true; // mark as ours
  255.         this.borderElems[i] = d;
  256.     }
  257.  
  258.     d = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
  259.     this.setElementStyleDefault (d, "#fff0cc");
  260.     d.style.borderTopWidth = "0";
  261.     d.style.MozBorderRadiusBottomleft = "6px";
  262.     d.style.MozBorderRadiusBottomright = "6px";
  263.     d.style.zIndex = "65535";
  264.     d.ehhAardvarkLabel = true; // mark as ours
  265.     this.labelElem = d;
  266. }
  267.  
  268. ehhAardvark.makeElementLabelString = function(elem) {
  269.     var s = "<b style='color:#000'>" + elem.tagName.toLowerCase() + "</b>";
  270.     if (elem.id != '')
  271.         s += ", id: " + elem.id;
  272.     if (elem.className != '')
  273.         s += ", class: " + elem.className;
  274.     /*for (var i in elem.style)
  275.         if (elem.style[i] != '')
  276.             s += "<br> " + i + ": " + elem.style[i]; */
  277.     if (elem.style.cssText != '')
  278.         s += ", style: " + elem.style.cssText;
  279.         
  280.     return s;
  281. }
  282.  
  283. ehhAardvark.showBoxAndLabel = function(elem, string) {
  284.     var doc = elem.ownerDocument;
  285.     if (!doc || !doc.body)
  286.         return;
  287.  
  288.     this.selectedElem = elem;
  289.  
  290.     for (var i = 0; i < 4; i++) {
  291.         try {
  292.             doc.adoptNode(this.borderElems[i]);
  293.         }
  294.         catch (e) {
  295.             // Gecko 1.8 doesn't implement adoptNode, ignore
  296.         }
  297.         doc.body.appendChild(this.borderElems[i]);
  298.     }
  299.  
  300.     var pos = this.getPos(elem)
  301.     var dims = this.getWindowDimensions (doc);
  302.  
  303.     this.borderElems[0].style.left
  304.         = this.borderElems[1].style.left
  305.         = this.borderElems[2].style.left
  306.         = (pos.x - 1) + "px";
  307.     this.borderElems[3].style.left = (pos.x + elem.offsetWidth - 1) + "px";
  308.  
  309.     this.borderElems[0].style.width
  310.         = this.borderElems[1].style.width
  311.         = (elem.offsetWidth + 2) + "px";
  312.  
  313.     this.borderElems[2].style.height
  314.         = this.borderElems[3].style.height
  315.         = (elem.offsetHeight + 2) + "px";
  316.  
  317.     this.borderElems[0].style.top
  318.         = this.borderElems[2].style.top
  319.         = this.borderElems[3].style.top
  320.         = (pos.y - 1) + "px";
  321.     this.borderElems[1].style.top = (pos.y + elem.offsetHeight - 1) + "px";
  322.     
  323.     this.borderElems[0].style.display
  324.         = this.borderElems[1].style.display
  325.         = this.borderElems[2].style.display
  326.         = this.borderElems[3].style.display
  327.         = "";
  328.     
  329.     var y = pos.y + elem.offsetHeight + 1;
  330.     
  331.     try {
  332.         doc.adoptNode(this.labelElem);
  333.     }
  334.     catch(e) {
  335.         // Gecko 1.8 doesn't implement adoptNode, ignore
  336.     }
  337.     doc.body.appendChild(this.labelElem);
  338.  
  339.     this.labelElem.innerHTML = string;
  340.     this.labelElem.style.display = "";
  341.  
  342.     // adjust the label as necessary to make sure it is within screen and
  343.     // the border is pretty
  344.     if ((y + this.labelElem.offsetHeight) >= dims.scrollY + dims.height)
  345.     {
  346.         this.labelElem.style.borderTopWidth = "1px";
  347.         this.labelElem.style.MozBorderRadiusTopleft = "6px";
  348.         this.labelElem.style.MozBorderRadiusTopright = "6px";
  349.         this.labelDrawnHigh = true;
  350.         y = (dims.scrollY + dims.height) - this.labelElem.offsetHeight;
  351.     }
  352.     else if (this.labelElem.offsetWidth > elem.offsetWidth)
  353.     {
  354.         this.labelElem.style.borderTopWidth = "1px";
  355.         this.labelElem.style.MozBorderRadiusTopright = "6px";
  356.         this.labelDrawnHigh = true;
  357.     }
  358.     else if (this.labelDrawnHigh)
  359.     {
  360.         this.labelElem.style.borderTopWidth = "0";
  361.         this.labelElem.style.MozBorderRadiusTopleft = "";
  362.         this.labelElem.style.MozBorderRadiusTopright = "";
  363.         delete (this.labelDrawnHigh); 
  364.     }
  365.     this.labelElem.style.left = (pos.x + 2) + "px";
  366.     this.labelElem.style.top = y + "px";
  367. }
  368.  
  369. ehhAardvark.clearBox = function() {
  370.     this.selectedElem = null;
  371.  
  372.     for (var i = 0; i < this.borderElems.length; i++)
  373.         if (this.borderElems[i].parentNode)
  374.             this.borderElems[i].parentNode.removeChild(this.borderElems[i]);
  375.  
  376.     if (this.labelElem.parentNode)
  377.         this.labelElem.parentNode.removeChild(this.labelElem);
  378. }
  379.  
  380. ehhAardvark.getPos = function (elem)
  381. {
  382.     var pos = {x: 0, y: 0};
  383.  
  384.     while (elem)
  385.     {
  386.         pos.x += elem.offsetLeft;
  387.         pos.y += elem.offsetTop;
  388.         elem = elem.offsetParent;
  389.     }
  390.     return pos;
  391. }
  392.  
  393. ehhAardvark.getWindowDimensions = function (doc)
  394. {
  395.     var out = {};
  396.  
  397.     out.scrollX = doc.body.scrollLeft + doc.documentElement.scrollLeft; 
  398.     out.scrollY = doc.body.scrollTop + doc.documentElement.scrollTop;
  399.  
  400.     if (doc.compatMode == "BackCompat")
  401.     {
  402.         out.width = doc.body.clientWidth;
  403.         out.height = doc.body.clientHeight;
  404.     }
  405.     else
  406.     {
  407.         out.width = doc.documentElement.clientWidth;
  408.         out.height = doc.documentElement.clientHeight;
  409.     }
  410.     return out;
  411. }
  412.  
  413. ehhAardvark.setElementStyleDefault = function (elem, bgColor)
  414. {
  415.     var s = elem.style;
  416.     s.display = "none";
  417.     s.backgroundColor = bgColor;
  418.     s.borderColor = "black";
  419.     s.borderWidth = "1px 2px 2px 1px";
  420.     s.borderStyle = "solid";
  421.     s.fontFamily = "arial";
  422.     s.textAlign = "left";
  423.     s.color = "#000";
  424.     s.fontSize = "12px";
  425.     s.position = "absolute";
  426.     s.paddingTop = "2px";
  427.     s.paddingBottom = "2px";
  428.     s.paddingLeft = "5px";
  429.     s.paddingRight = "5px";
  430. }
  431.  
  432. /*********************************
  433.  * Code from aardvarkCommands.js *
  434.  *********************************/
  435.  
  436. //------------------------------------------------------------
  437. // 0: name, 1: needs element
  438. ehhAardvark.commands = [
  439.     "select",
  440.     "wider",
  441.     "narrower",
  442.     "quit",
  443.     "blinkElement",
  444.     "viewSource",
  445.     "viewSourceWindow",
  446.     "showMenu"
  447. ];
  448.  
  449. //------------------------------------------------------------
  450. ehhAardvark.wider = function (elem)
  451. {
  452.     if (elem)
  453.     {
  454.         var newElem = elem.parentNode;
  455.         if (newElem && newElem.nodeType == newElem.DOCUMENT_NODE && newElem.defaultView && !(newElem.defaultView.frameElement instanceof HTMLFrameElement))
  456.             newElem = newElem.defaultView.frameElement;
  457.  
  458.         if (!newElem || newElem.nodeType != newElem.ELEMENT_NODE)
  459.             return false;
  460.         
  461.         if (this.widerStack && this.widerStack.length>0 && 
  462.             this.widerStack[this.widerStack.length-1] == elem)
  463.         {
  464.             this.widerStack.push (newElem);
  465.         }
  466.         else
  467.         {
  468.             this.widerStack = [elem, newElem];
  469.         }
  470.         this.showBoxAndLabel (newElem, 
  471.                 this.makeElementLabelString (newElem));
  472.         return true;
  473.     }
  474.     return false;
  475.  
  476. //------------------------------------------------------------
  477. ehhAardvark.narrower = function (elem)
  478. {
  479.     if (elem)
  480.     {
  481.         if (this.widerStack && this.widerStack.length>1 && 
  482.             this.widerStack[this.widerStack.length-1] == elem)
  483.         {
  484.             this.widerStack.pop();
  485.             var newElem = this.widerStack[this.widerStack.length-1];
  486.             this.showBoxAndLabel (newElem, 
  487.                     this.makeElementLabelString (newElem));
  488.             return true;
  489.         }
  490.     }
  491.     return false;
  492. }
  493.     
  494. //------------------------------------------------------------
  495. ehhAardvark.quit = function ()
  496. {
  497.     if (!this.browser)
  498.         return false;
  499.  
  500.     this.clearBox();
  501.     ehhHideTooltips();
  502.     
  503.     this.browser.removeEventListener("click", this.mouseClick, true);
  504.     this.browser.removeEventListener("mouseover", this.mouseOver, true);
  505.     this.browser.removeEventListener("keypress", this.keyPress, true);
  506.     this.browser.removeEventListener("mousemove", this.mouseMove, true);
  507.     this.browser.contentWindow.removeEventListener("pagehide", this.pageHide, true);
  508.  
  509.     this.selectedElem = null;
  510.     this.browser = null;
  511.     this.commentElem = null;
  512.     delete this.widerStack;
  513.     return true;
  514. }
  515.  
  516. //------------------------------------------------------------
  517. ehhAardvark.select = function (elem)
  518. {
  519.     if (!elem || !this.quit())
  520.         return false;
  521.  
  522.     window.openDialog("chrome://elemhidehelper/content/composer.xul", "_blank",
  523.                                         "chrome,centerscreen,resizable,dialog=no", elem);
  524.     return true;
  525. }
  526.  
  527. //------------------------------------------------------------
  528. ehhAardvark.blinkElement = function (elem)
  529. {
  530.     if (!elem)
  531.         return false;
  532.  
  533.     if ("blinkInterval" in this)
  534.         this.stopBlinking();
  535.  
  536.     var counter = 0;
  537.     this.blinkElem = elem;
  538.     this.blinkOrigValue = elem.style.visibility;
  539.     this.blinkInterval = setInterval(function() {
  540.         counter++;
  541.         elem.style.visibility = (counter % 2 == 0 ? "visible" : "hidden");
  542.         if (counter == 6)
  543.             ehhAardvark.stopBlinking();
  544.     }, 250);
  545.  
  546.     return true;
  547. }
  548. ehhAardvark.stopBlinking = function() {
  549.     clearInterval(this.blinkInterval);
  550.     this.blinkElem.style.visibility = this.blinkOrigValue;
  551.  
  552.     delete this.blinkElem;
  553.     delete this.blinkOrigValue;
  554.     delete this.blinkInterval;
  555. }
  556.  
  557. //------------------------------------------------------------
  558. ehhAardvark.viewSource = function (elem)
  559. {
  560.     if (!elem)
  561.         return false;
  562.  
  563.     var sourceBox = document.getElementById("ehh-viewsource");
  564.     if ((sourceBox.getAttribute("_moz-menuactive") == "true" || sourceBox.state == "open") && this.commentElem == elem) {
  565.         sourceBox.hidePopup();
  566.         return true;
  567.     }
  568.     sourceBox.hidePopup();
  569.  
  570.     while (sourceBox.firstChild)
  571.         sourceBox.removeChild(sourceBox.firstChild);
  572.     this.getOuterHtmlFormatted(elem, sourceBox);
  573.     this.commentElem = elem;
  574.  
  575.     var x = this.mouseX;
  576.     var y = this.mouseY;
  577.     setTimeout(function() {
  578.         sourceBox.showPopup(document.documentElement, x, y, "tooltip", "topleft", "topleft");
  579.     }, 500);
  580.     return true;
  581. }
  582.  
  583. //--------------------------------------------------------
  584. ehhAardvark.viewSourceWindow = function(elem) {
  585.     if (!elem || !this.viewSourceURL)
  586.         return false;
  587.  
  588.     var range = elem.ownerDocument.createRange();
  589.     range.selectNodeContents(elem);
  590.     var selection = {rangeCount: 1, getRangeAt: function() {return range}};
  591.  
  592.     // SeaMonkey uses a different 
  593.     window.openDialog(this.viewSourceURL, "_blank", "scrollbars,resizable,chrome,dialog=no",
  594.                                         null, null, selection, "selection");
  595.     return true;
  596. }
  597.  
  598. //--------------------------------------------------------
  599. ehhAardvark.getOuterHtmlFormatted = function (node, container)
  600. {
  601.     var type = null;
  602.     switch (node.nodeType) {
  603.         case node.ELEMENT_NODE:
  604.             var box = document.createElement("vbox");
  605.             box.className = "elementBox";
  606.  
  607.             var startTag = document.createElement("hbox");
  608.             startTag.className = "elementStartTag";
  609.             if (!node.firstChild)
  610.                 startTag.className += "elementEndTag";
  611.  
  612.             this.appendDescription(startTag, "<", null);
  613.             this.appendDescription(startTag, node.tagName, "tagName");
  614.  
  615.             for (var i = 0; i < node.attributes.length; i++) {
  616.                 var attr = node.attributes[i];
  617.                 this.appendDescription(startTag, attr.name, "attrName");
  618.                 if (attr.value != "") {
  619.                     this.appendDescription(startTag, "=", null);
  620.                     this.appendDescription(startTag, '"' + attr.value.replace(/"/, """) + '"', "attrValue");
  621.                 }
  622.             }
  623.  
  624.             this.appendDescription(startTag, node.firstChild ? ">" : " />", null);
  625.             box.appendChild(startTag);
  626.  
  627.             if (node.firstChild) {
  628.                 for (var child = node.firstChild; child; child = child.nextSibling)
  629.                     this.getOuterHtmlFormatted(child, box);
  630.  
  631.                 var endTag = document.createElement("hbox");
  632.                 endTag.className = "elementEndTag";
  633.                 this.appendDescription(endTag, "<", null);
  634.                 this.appendDescription(endTag, "/" + node.tagName, "tagName");
  635.                 this.appendDescription(endTag, ">", null);
  636.                 box.appendChild(endTag);
  637.             }
  638.             container.appendChild(box);
  639.             return;
  640.  
  641.         case node.TEXT_NODE:
  642.             type = "text";
  643.             break;
  644.         case node.CDATA_SECTION_NODE:
  645.             type = "cdata";
  646.             break;
  647.         case node.COMMENT_NODE:
  648.             type = "comment";
  649.             break;
  650.         default:
  651.             return;
  652.     }
  653.  
  654.     var text = node.nodeValue.replace(/\r/g, '').replace(/^\s+/, '').replace(/\s+$/, '');
  655.     if (text == "")
  656.         return;
  657.  
  658.     if (type != "cdata") {
  659.         text = text.replace(/&/g, "&")
  660.                              .replace(/</g, "<")
  661.                              .replace(/>/g, ">");
  662.     }
  663.     text = text.replace(/\t/g, "  ");
  664.     if (type == "cdata")
  665.         text = "<![CDATA[" + text + "]]>";
  666.     else if (type == "comment")
  667.         text = "<!--" + text + "-->";
  668.  
  669.     var lines = text.split("\n");
  670.     for (var i = 0; i < lines.length; i++)
  671.         this.appendDescription(container, lines[i].replace(/^\s+/, '').replace(/\s+$/, ''), type);
  672. }
  673.  
  674. //-------------------------------------------------
  675. ehhAardvark.showMenu = function ()
  676. {
  677.     var helpBox = document.getElementById("ehh-helpbox");
  678.     if (helpBox.getAttribute("_moz-menuactive") == "true" || helpBox.state == "open") {
  679.         helpBox.hidePopup();
  680.         return true;
  681.     }
  682.  
  683.     // Show help box
  684.     helpBox.showPopup(this.browser, -1, -1, "tooltip", "topleft", "topleft");
  685.     return true;
  686. }
  687.